<template>
  <div class="workflow-designer">
    <!-- 左侧菜单 -->
    <div class="sidebar">
      <h3>节点库</h3>
      <div class="node-menu">
        <div 
          v-for="nodeType in nodeTypes" 
          :key="nodeType.type"
          class="node-item"
          draggable="true"
          @dragstart="onDragStart($event, nodeType)"
        >
          <div class="node-icon" :class="nodeType.type">
            <el-icon><component :is="nodeType.icon" /></el-icon>
          </div>
          <span class="node-label">{{ nodeType.label }}</span>
        </div>
      </div>
    </div>

    <!-- 右侧画布区域 -->
    <div class="canvas-container">
      <!-- 工具栏 -->
      <div class="toolbar">
        <el-button @click="clearCanvas" type="danger" size="small">
          <el-icon><Delete /></el-icon>
          清空画布
        </el-button>
        <el-button @click="exportWorkflow" type="primary" size="small">
          <el-icon><Download /></el-icon>
          导出工作流
        </el-button>
        <el-button @click="importWorkflow" size="small">
          <el-icon><Upload /></el-icon>
          导入工作流
        </el-button>
        <el-button @click="importElsaWorkflow" type="warning" size="small">
          <el-icon><Document /></el-icon>
          导入Elsa格式
        </el-button>
        <el-button @click="saveToElsa" type="success" size="small">
          <el-icon><Document /></el-icon>
          保存为Elsa格式
        </el-button>
      </div>
      
      <VueFlow
        :node-types="customNodeTypes"
        @node-drag-stop="onNodeDragStop"
        @connect="onConnect"
        @drop="onDrop"
        @dragover="onDragOver"
        @node-double-click="onNodeDoubleClick"
        @node-context-menu="onNodeContextMenu"
        @edge-context-menu="onEdgeContextMenu"
        class="vue-flow-container"
      >
        <Background />
        <Controls />
        <MiniMap />
      </VueFlow>
    </div>

    <!-- 人员选择弹窗 -->
    <PersonSelector
      v-model="personSelectorVisible"
      :title="personSelectorTitle"
      :selected-person-ids="getCurrentSelectedPersonIds()"
      @confirm="handlePersonSelection"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { VueFlow, useVueFlow } from '@vue-flow/core'
import { Background } from '@vue-flow/background'
import { Controls } from '@vue-flow/controls'
import { MiniMap } from '@vue-flow/minimap'
import { ElIcon } from 'element-plus'
import { 
  Delete,
  Download,
  Upload,
  Document
} from '@element-plus/icons-vue'

// 导入自定义节点组件
import StartNode from './nodes/StartNode.vue'
import ApproveNode from './nodes/ApproveNode.vue'
import SendNode from './nodes/SendNode.vue'
import EndNode from './nodes/EndNode.vue'
import PersonSelector from './PersonSelector.vue'

// 节点类型定义
const nodeTypes = [
  { type: 'start', label: '开始', icon: 'VideoPlay' },
  { type: 'approve', label: '审批', icon: 'User' },
  { type: 'send', label: '抄送', icon: 'Message' },
  { type: 'end', label: '结束', icon: 'CircleCheck' }
]

// 自定义节点类型
const customNodeTypes: any = {
  start: StartNode,
  approve: ApproveNode,
  send: SendNode,
  end: EndNode
}

// 使用Vue Flow的状态管理
const { addNodes, addEdges, removeNodes, removeEdges, nodes, edges } = useVueFlow()

// 初始化一个开始节点
const initialNodes = [
  {
    id: 'start-1',
    type: 'start',
    position: { x: 100, y: 100 },
    data: { label: '开始', type: 'start' }
  }
]

// 设置初始节点
addNodes(initialNodes)

// 人员选择弹窗状态
const personSelectorVisible = ref(false)
const personSelectorTitle = ref('')
const currentEditingNodeId = ref('')
const currentEditingType = ref('')

// 拖拽开始事件
const onDragStart = (event: DragEvent, nodeType: any) => {
  if (event.dataTransfer) {
    event.dataTransfer.setData('application/vueflow', JSON.stringify(nodeType))
    event.dataTransfer.effectAllowed = 'move'
  }
}

// 拖拽悬停事件
const onDragOver = (event: DragEvent) => {
  event.preventDefault()
  event.dataTransfer!.dropEffect = 'move'
}

// 拖拽放置事件
const onDrop = (event: DragEvent) => {
  event.preventDefault()
  
  const nodeTypeData = event.dataTransfer?.getData('application/vueflow')
  if (!nodeTypeData) return
  
  const nodeType = JSON.parse(nodeTypeData)
  
  // 获取Vue Flow容器的位置
  const flowContainer = document.querySelector('.vue-flow-container')
  if (!flowContainer) return
  
  const rect = flowContainer.getBoundingClientRect()
  
  // 计算相对于Vue Flow画布的位置
  const position = {
    x: event.clientX - rect.left,
    y: event.clientY - rect.top
  }
  
  // 创建新节点
  const newNode = {
    id: `${nodeType.type}-${Date.now()}`,
    type: nodeType.type,
    position,
    data: {
      label: nodeType.label,
      type: nodeType.type
    }
  }
  
  // 使用Vue Flow的addNodes方法
  addNodes([newNode])
}

// 节点拖拽停止事件
const onNodeDragStop = (event: any) => {
  console.log('节点拖拽停止:', event)
}

// 连接事件
const onConnect = (params: any) => {
  const newEdge = {
    id: `edge-${Date.now()}`,
    source: params.source,
    target: params.target,
    type: 'smoothstep',
    animated: true,
    style: {
      strokeWidth: 3,
      stroke: '#1890ff'
    }
  }
  
  addEdges([newEdge])
}

// 节点双击事件
const onNodeDoubleClick = (event: any) => {
  const nodeId = event.node.id
  const nodeType = event.node.type
  
  if (nodeType === 'approve') {
    editApprover(nodeId)
  } else if (nodeType === 'send') {
    editRecipients(nodeId)
  }
}

// 节点右键菜单事件
const onNodeContextMenu = (event: any) => {
  event.event.preventDefault()
  const nodeId = event.node.id
  
  // 简单的确认删除
  if (confirm('确定要删除这个节点吗？')) {
    deleteNode(nodeId)
  }
}

// 连接线右键菜单事件
const onEdgeContextMenu = (event: any) => {
  event.event.preventDefault()
  const edgeId = event.edge.id
  
  // 简单的确认删除
  if (confirm('确定要删除这条连接线吗？')) {
    deleteEdge(edgeId)
  }
}

// 编辑审批人
const editApprover = (nodeId: string) => {
  currentEditingNodeId.value = nodeId
  currentEditingType.value = 'approve'
  personSelectorTitle.value = '选择审批人'
  personSelectorVisible.value = true
}

// 编辑抄送人
const editRecipients = (nodeId: string) => {
  currentEditingNodeId.value = nodeId
  currentEditingType.value = 'send'
  personSelectorTitle.value = '选择抄送人'
  personSelectorVisible.value = true
}

// 人员选择确认
const handlePersonSelection = (personIds: string[], persons: any[]) => {
  const node = nodes.value.find(n => n.id === currentEditingNodeId.value)
  if (!node) return
  
  if (currentEditingType.value === 'approve') {
    node.data.approverIds = personIds
    node.data.approver = persons.map(p => p.name).join(', ')
  } else if (currentEditingType.value === 'send') {
    node.data.recipientIds = personIds
    node.data.recipients = persons.map(p => p.name).join(', ')
  }
}

// 获取当前选中的人员ID
const getCurrentSelectedPersonIds = () => {
  const node = nodes.value.find(n => n.id === currentEditingNodeId.value)
  if (!node) return []
  
  if (currentEditingType.value === 'approve') {
    return node.data.approverIds || []
  } else if (currentEditingType.value === 'send') {
    return node.data.recipientIds || []
  }
  
  return []
}

// 删除节点
const deleteNode = (nodeId: string) => {
  // 删除相关的边
  const edgesToRemove = edges.value.filter(e => e.source === nodeId || e.target === nodeId)
  if (edgesToRemove.length > 0) {
    removeEdges(edgesToRemove)
  }
  
  // 删除节点
  removeNodes([nodeId])
}

// 删除连接线
const deleteEdge = (edgeId: string) => {
  removeEdges([edgeId])
}

// 清空画布
const clearCanvas = () => {
  if (confirm('确定要清空整个画布吗？')) {
    removeNodes(nodes.value.map(n => n.id))
    removeEdges(edges.value.map(e => e.id))
  }
}

// 导出工作流
const exportWorkflow = () => {
  const workflow = {
    nodes: nodes.value,
    edges: edges.value,
    timestamp: new Date().toISOString()
  }
  
  const dataStr = JSON.stringify(workflow, null, 2)
  const dataBlob = new Blob([dataStr], { type: 'application/json' })
  const url = URL.createObjectURL(dataBlob)
  
  const link = document.createElement('a')
  link.href = url
  link.download = `workflow-${Date.now()}.json`
  link.click()
  
  URL.revokeObjectURL(url)
}

// 导入工作流
const importWorkflow = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.json'
  
  input.onchange = (event: any) => {
    const file = event.target.files[0]
    if (file) {
      const reader = new FileReader()
      reader.onload = (e: any) => {
        try {
          const workflow = JSON.parse(e.target.result)
          if (workflow.nodes && workflow.edges) {
            // 清空现有内容
            removeNodes(nodes.value.map(n => n.id))
            removeEdges(edges.value.map(e => e.id))
            
            // 添加新内容
            addNodes(workflow.nodes)
            addEdges(workflow.edges)
            alert('工作流导入成功！')
          } else {
            alert('文件格式不正确！')
          }
        } catch (error) {
          alert('文件解析失败！')
        }
      }
      reader.readAsText(file)
    }
  }
  
  input.click()
}

// 导入Elsa格式工作流
const importElsaWorkflow = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.json'
  
  input.onchange = (event: any) => {
    const file = event.target.files[0]
    if (file) {
      const reader = new FileReader()
      reader.onload = (e: any) => {
        try {
          const elsaWorkflow = JSON.parse(e.target.result)
          const vueFlowData = convertElsaToVueFlow(elsaWorkflow)
          
          if (vueFlowData) {
            // 清空现有内容
            removeNodes(nodes.value.map(n => n.id))
            removeEdges(edges.value.map(e => e.id))
            
            // 添加转换后的内容
            addNodes(vueFlowData.nodes)
            addEdges(vueFlowData.edges)
            alert('Elsa工作流导入成功！')
          } else {
            alert('Elsa格式转换失败！')
          }
        } catch (error) {
          console.error('Elsa格式解析失败:', error)
          alert('文件解析失败！请确保是有效的Elsa工作流格式。')
        }
      }
      reader.readAsText(file)
    }
  }
  
  input.click()
}

// 保存为Elsa格式
const saveToElsa = () => {
  try {
    const elsaWorkflow = convertToElsaFormat(nodes.value, edges.value)
    console.log('Elsa工作流数据:', elsaWorkflow)
    alert('Elsa格式数据已保存到控制台！')
  } catch (error) {
    console.error('转换Elsa格式失败:', error)
    alert('转换失败，请检查控制台错误信息')
  }
}

// 转换为Elsa框架格式
const convertToElsaFormat = (nodes: any[], edges: any[]) => {
  const elsaWorkflow: any = {
    id: `workflow-${Date.now()}`,
    name: '工作流设计',
    description: '通过Vue Flow设计器创建的工作流',
    version: 1,
    isPublished: false,
    isLatest: true,
    activities: [],
    connections: [],
    variables: [],
    customAttributes: [],
    persistenceBehavior: {
      workflowDefinitionId: '',
      workflowInstanceId: '',
      workflowInstanceName: '',
      workflowInstanceVersion: 1,
      correlationId: '',
      contextId: '',
      contextType: '',
      tenantId: '',
      isSystem: false
    }
  }

  // 转换节点为Elsa活动
  nodes.forEach(node => {
    const activity = convertNodeToElsaActivity(node)
    if (activity) {
      elsaWorkflow.activities.push(activity)
    }
  })

  // 转换边为Elsa连接
  edges.forEach(edge => {
    const connection = convertEdgeToElsaConnection(edge)
    if (connection) {
      elsaWorkflow.connections.push(connection)
    }
  })

  return elsaWorkflow
}

// 转换节点为Elsa活动
const convertNodeToElsaActivity = (node: any) => {
  const baseActivity = {
    id: node.id,
    type: '',
    name: node.data.label,
    displayName: node.data.label,
    description: '',
    x: node.position.x,
    y: node.position.y,
    properties: [],
    propertyStorageProviders: {},
    outcomes: [],
    persistWorkflow: false,
    loadWorkflowContext: false,
    saveWorkflowContext: false,
    attributes: {
      'x': node.position.x,
      'y': node.position.y
    }
  }

  switch (node.type) {
    case 'start':
      return {
        ...baseActivity,
        type: 'Start',
        outcomes: ['Done']
      }
    
    case 'approve':
      return {
        ...baseActivity,
        type: 'Approval',
        properties: [
          {
            name: 'Approver',
            value: node.data.approver || '请设置审批人',
            expressions: {}
          }
        ],
        outcomes: ['Approved', 'Rejected']
      }
    
    case 'send':
      return {
        ...baseActivity,
        type: 'SendEmail',
        properties: [
          {
            name: 'Recipients',
            value: node.data.recipients || '请设置抄送人',
            expressions: {}
          },
          {
            name: 'Subject',
            value: '工作流通知',
            expressions: {}
          },
          {
            name: 'Body',
            value: '您有一个新的工作流任务需要处理。',
            expressions: {}
          }
        ],
        outcomes: ['Done']
      }
    
    case 'end':
      return {
        ...baseActivity,
        type: 'Finish',
        outcomes: []
      }
    
    default:
      return null
  }
}

// 转换边为Elsa连接
const convertEdgeToElsaConnection = (edge: any) => {
  return {
    id: edge.id,
    sourceActivityId: edge.source,
    targetActivityId: edge.target,
    outcome: 'Done', // 默认输出
    sourcePort: {
      name: 'Done',
      displayName: 'Done'
    },
    targetPort: {
      name: 'In',
      displayName: 'In'
    }
  }
}

// 将Elsa格式转换为Vue Flow格式
const convertElsaToVueFlow = (elsaWorkflow: any) => {
  try {
    if (!elsaWorkflow.activities || !Array.isArray(elsaWorkflow.activities)) {
      console.error('Elsa工作流格式无效：缺少activities数组')
      return null
    }

    const vueFlowNodes: any[] = []
    const vueFlowEdges: any[] = []

    // 转换活动为节点
    elsaWorkflow.activities.forEach((activity: any) => {
      const node = convertElsaActivityToNode(activity)
      if (node) {
        vueFlowNodes.push(node)
      }
    })

    // 转换连接为边
    if (elsaWorkflow.connections && Array.isArray(elsaWorkflow.connections)) {
      elsaWorkflow.connections.forEach((connection: any) => {
        const edge = convertElsaConnectionToEdge(connection)
        if (edge) {
          vueFlowEdges.push(edge)
        }
      })
    }

    return {
      nodes: vueFlowNodes,
      edges: vueFlowEdges
    }
  } catch (error) {
    console.error('Elsa格式转换失败:', error)
    return null
  }
}

// 将Elsa活动转换为Vue Flow节点
const convertElsaActivityToNode = (activity: any) => {
  try {
    let nodeType = ''
    let label = activity.displayName || activity.name || '未知节点'
    let data: any = {
      label,
      type: nodeType
    }

    // 根据Elsa活动类型确定Vue Flow节点类型
    switch (activity.type) {
      case 'Start':
        nodeType = 'start'
        break
      case 'Approval':
        nodeType = 'approve'
        // 提取审批人信息
        const approverProperty = activity.properties?.find((p: any) => p.name === 'Approver')
        if (approverProperty) {
          data.approver = approverProperty.value || '请设置审批人'
          data.approverIds = [approverProperty.value] // 简化处理，实际可能需要更复杂的映射
        }
        break
      case 'SendEmail':
        nodeType = 'send'
        // 提取收件人信息
        const recipientsProperty = activity.properties?.find((p: any) => p.name === 'Recipients')
        if (recipientsProperty) {
          data.recipients = recipientsProperty.value || '请设置抄送人'
          data.recipientIds = [recipientsProperty.value] // 简化处理
        }
        break
      case 'Finish':
        nodeType = 'end'
        break
      default:
        // 对于未知类型，尝试根据名称推断
        if (label.includes('开始') || label.includes('Start')) {
          nodeType = 'start'
        } else if (label.includes('审批') || label.includes('Approval')) {
          nodeType = 'approve'
        } else if (label.includes('抄送') || label.includes('Send') || label.includes('Email')) {
          nodeType = 'send'
        } else if (label.includes('结束') || label.includes('End') || label.includes('Finish')) {
          nodeType = 'end'
        } else {
          console.warn(`未知的Elsa活动类型: ${activity.type}`)
          return null
        }
    }

    // 获取位置信息
    const position = {
      x: activity.x || activity.attributes?.x || 100,
      y: activity.y || activity.attributes?.y || 100
    }

    return {
      id: activity.id,
      type: nodeType,
      position,
      data: {
        ...data,
        type: nodeType
      }
    }
  } catch (error) {
    console.error('转换Elsa活动失败:', error, activity)
    return null
  }
}

// 将Elsa连接转换为Vue Flow边
const convertElsaConnectionToEdge = (connection: any) => {
  try {
    return {
      id: connection.id || `edge-${Date.now()}-${Math.random()}`,
      source: connection.sourceActivityId,
      target: connection.targetActivityId,
      type: 'smoothstep',
      animated: true,
      style: {
        strokeWidth: 3,
        stroke: '#1890ff'
      }
    }
  } catch (error) {
    console.error('转换Elsa连接失败:', error, connection)
    return null
  }
}
</script>

<style scoped>
.workflow-designer {
  display: flex;
  height: 100vh;
  background: #f5f5f5;
}

.sidebar {
  width: 250px;
  background: white;
  border-right: 1px solid #e0e0e0;
  padding: 20px;
  box-shadow: 2px 0 4px rgba(0,0,0,0.1);
}

.sidebar h3 {
  margin: 0 0 20px 0;
  color: #333;
  font-size: 16px;
  font-weight: 600;
}

.node-menu {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.node-item {
  display: flex;
  align-items: center;
  padding: 12px;
  background: #f8f9fa;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  cursor: grab;
  transition: all 0.2s ease;
  user-select: none;
}

.node-item:hover {
  background: #e9ecef;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.node-item:active {
  cursor: grabbing;
}

.node-icon {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 12px;
  font-size: 16px;
  color: white;
}

.node-icon.start {
  background: #52c41a;
}

.node-icon.approve {
  background: #1890ff;
}

.node-icon.send {
  background: #faad14;
}

.node-icon.end {
  background: #ff4d4f;
}

.node-label {
  font-size: 14px;
  color: #333;
  font-weight: 500;
}

.canvas-container {
  flex: 1;
  position: relative;
  display: flex;
  flex-direction: column;
}

.toolbar {
  padding: 12px 16px;
  background: white;
  border-bottom: 1px solid #e0e0e0;
  display: flex;
  gap: 8px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.vue-flow-container {
  flex: 1;
  background: #fafafa;
}

/* 自定义连接线样式 */
:deep(.vue-flow__edge-path) {
  stroke-width: 3px;
  stroke: #1890ff;
}

:deep(.vue-flow__edge.selected .vue-flow__edge-path) {
  stroke: #ff4d4f;
  stroke-width: 4px;
}

:deep(.vue-flow__edge.animated .vue-flow__edge-path) {
  stroke-dasharray: 5;
  animation: dashdraw 0.5s linear infinite;
}

@keyframes dashdraw {
  to {
    stroke-dashoffset: -10;
  }
}
</style>
